﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Data;
using SMSPanasonic.Business;
using System.Text.RegularExpressions;
using SMSPanasonic.Data;
using System.Data.SqlClient;

namespace SMSPanasonic
{
    class SMSMTAutoSend
    {
        private EventLog _serviceEventLog;
        private bool _thread_working_flag = false;
        private bool _serviceStarted;
        private int _interval = Properties.Settings.Default.IntevalDefaultGetReport;
        private static object _log = new object();
        public bool ServiceStarted
        {
            get
            {
                return _serviceStarted;
            }
            set
            {
                _serviceStarted = value;
            }
        }
        
        public int Interval
        {
            get
            {
                return _interval;
            }
        }

        public SMSMTAutoSend(EventLog log)
        {
            _serviceEventLog = log;
        }

        public void ExecuteTask()
        {
            DateTime lastRunTime = DateTime.Now;
            while (_serviceStarted)
            {
                if (((TimeSpan)(DateTime.Now.Subtract(lastRunTime))).TotalMilliseconds >= _interval && !_thread_working_flag && CanExecute())
                {
                    _thread_working_flag = true;
                    try
                    {
                        if (Common.isDatabaseAlive(AppConfig.ConnectionString) == ConnectionState.Open)
                        {
                            lock (_log)//Mỗi lượt xử lý dữ liệu thì phải lock lại không cho phép nhiều thread
                            {
                                DataTable dtSource = pa_WarrantyWaiting.GetByAutoSendSms(AppConfig.BatchSize);
                                while (dtSource.Rows.Count > 0)
                                {
                                    ProcessingData(dtSource);
                                    dtSource = pa_WarrantyWaiting.GetByAutoSendSms(AppConfig.BatchSize);
                                }
                            }
                        }
                    }
                    catch (Exception ext)
                    {
                        try
                        {
                            Common.WriteLog(ext, "SMSMTAutoSend");
                        }
                        catch (Exception extend)
                        {
                            _serviceEventLog.WriteEntry(extend.Message);
                        }
                    }
                    finally
                    {
                        _thread_working_flag = false;
                    }
                }
                // yield
                if (_serviceStarted)
                {
                    Thread.Sleep(new TimeSpan(0, 0, 0, 0, 100));
                }
            }
            Thread.CurrentThread.Abort();
        }

        #region Private method
        private void ProcessingData(DataTable dtSource)
        {
            if (dtSource == null || dtSource.Rows.Count == 0) return;
            DataTable dtMtReport = MakeBulkTable.MakeSmsMtReportTable();
            DataTable dtMtWaiting = MakeBulkTable.MakeSmsMtWaitingTable();
            DataTable dtWarrantyWaiting = MakeBulkTable.MakeWarrantyWaitingTable();
            try
            {
                foreach (DataRow row in dtSource.Rows)
                {
                    pa_WarrantyWaiting objWaiting = new pa_WarrantyWaiting(row);
                    try
                    {
                        string message = MessagePattern.GetMessage(objWaiting);
                        if (!string.IsNullOrEmpty(message))
                        {
                            if (pa_Warranty.Insert(objWaiting, message))
                            {
                                //Nếu số điện thoại là số di động
                                if (OperatorPrefixCode.IsMobilePhone(objWaiting.CustomerPhone))
                                {
                                    //Xử lý dữ liệu mt waiting
                                    DataRow mtRow = dtMtWaiting.NewRow();
                                    SmsMtWaiting.SetDataRow(ref mtRow, message, AppConfig.DefaultShortCode, objWaiting.CustomerPhone, row["AgencyID"]);
                                    dtMtWaiting.Rows.Add(mtRow);
                                    dtMtReport.Rows.Add(mtRow["mtGuid"], mtRow["SentTime"], mtRow["Status"]);
                                }
                            }
                        }
                        else
                        {
                            dtWarrantyWaiting.Rows.Add(DBNull.Value, objWaiting.ModelCode, objWaiting.ProductCode, objWaiting.AgencyID,
                                                        objWaiting.CustomerPhone, objWaiting.WarrantyPackageCode ?? (object)DBNull.Value, objWaiting.RegisterDate,
                                                        objWaiting.WarrantyType ?? (object)DBNull.Value, false, false, objWaiting.CreatedDate, DateTime.Now,
                                                        objWaiting.RegisteredFrom, objWaiting.RegisteredPhone ?? (object)DBNull.Value, objWaiting.Description ?? (object)DBNull.Value);
                        }
                    }
                    catch (Exception ex)
                    {
                        try
                        {
                            dtWarrantyWaiting.Rows.Add(DBNull.Value, objWaiting.ModelCode, objWaiting.ProductCode, objWaiting.AgencyID,
                                                        objWaiting.CustomerPhone, objWaiting.WarrantyPackageCode ?? (object)DBNull.Value, objWaiting.RegisterDate,
                                                        objWaiting.WarrantyType ?? (object)DBNull.Value, false, false, objWaiting.CreatedDate, DateTime.Now,
                                                        objWaiting.RegisteredFrom, objWaiting.RegisteredPhone ?? (object)DBNull.Value, objWaiting.Description ?? (object)DBNull.Value);
                            Common.WriteLog(ex, "SMSMTAutoSend");
                        }
                        catch (Exception extend)
                        {
                            _serviceEventLog.WriteEntry(extend.Message);
                        }
                    }
                }

                #region Insert dữ liệu vào các bảng dữ liệu
                //Insert dữ liệu vào pa_WarrantyWaiting
                if (dtWarrantyWaiting.Rows.Count > 0)
                {
                    pa_WarrantyWaiting.Insert(dtWarrantyWaiting);
                }
                //Insert dữ liệu vào SmsMtReport
                if (dtMtReport.Rows.Count > 0)
                {
                    SmsMtReport.Insert(dtMtReport);
                }
                //Insert dữ liệu vào SmsMtStatistic và SmsMtWaiting
                if (dtMtWaiting.Rows.Count > 0)
                {
                    SmsMtStatistic.Insert(dtMtWaiting);
                    SmsMtWaiting.Insert(dtMtWaiting);
                }
                #endregion Insert dữ liệu vào các bảng dữ liệu
            }
            catch (Exception ex)
            {
                try
                {
                    Common.WriteLog(ex, "SMSMTAutoSend");
                }
                catch (Exception extend)
                {
                    _serviceEventLog.WriteEntry(extend.Message);
                }
            }
            finally
            {
                dtSource.Dispose();
                dtMtReport.Dispose();
                dtMtWaiting.Dispose();
                dtWarrantyWaiting.Dispose();
            }
        }

        private bool CanExecute()
        {
            DateTime currentTime = DateTime.Now;
            TimeSpan[] runat = AppConfig.MTAutoSendAt;
            for (int i = 0; i < runat.Length; i++)
            {
                if (Math.Abs((runat[i] - currentTime.TimeOfDay).TotalMilliseconds) <= Interval)
                {
                    return true;
                }
            }
            //return true;
            return false;
        }
        #endregion
    }
}
